#include <signal.h>

#include <iostream>
using std::cout;
using std::endl;

#include <workflow/WFFacilities.h>
#include <workflow/MySQLResult.h>
#include <workflow/MySQLUtil.h>
#include <wfrest/HttpServer.h>
#include <wfrest/json.hpp>

using std::vector;

//通过构造函数初始化计数器的值 
static WFFacilities::WaitGroup waitGroup(1);

void sighandler(int num)
{
    printf("sig %d is coming\n", num);
    //将计数器的值减1
    waitGroup.done();
}


void test0()
{
    using std::string;
    signal(SIGINT, sighandler);
    using namespace wfrest;
    HttpServer httpserver;

    httpserver.GET("/wfrest/test0", [](const HttpReq*, HttpResp*resp){
        resp->String("hello,wfrest client2");
    });

    //部署静态资源
    httpserver.GET("/wfrest/file", [](const HttpReq*, HttpResp*resp){
        resp->File("postform.html");
    });

    //响应JSON
    httpserver.GET("/wfrest/json", [](const HttpReq*, HttpResp*resp){
        Json data;
        data["username"] = "liubei";
        data["password"] = "123";
        resp->Json(data);
    });

    httpserver.GET("/wfrest/mysql0", [](const HttpReq*, HttpResp*resp){
        string url("mysql://root:1234@localhost");
        string sql("select * from cloudisk.tbl_user_token");
        resp->MySQL(url, sql);
    });

    httpserver.GET("/wfrest/mysql1", [](const HttpReq*, HttpResp*resp){
        string url("mysql://root:1234@localhost");
        string sql("select * from cloudisk.tbl_user_token");
        //json指针指向的就是MySQL的结果集
        resp->MySQL(url, sql, [resp](Json * json){
            string msg = (*json)["result_set"][0]["rows"][0][1];
            resp->String(msg);
        });
    });

    httpserver.GET("/wfrest/mysql2", [](const HttpReq*, HttpResp*resp){
        string url("mysql://root:1234@localhost");
        string sql("select * from cloudisk.tbl_user_token");
        using namespace protocol;
        //pcursor指针指向的就是MySQL的结果集的迭代器
        resp->MySQL(url, sql, [resp](MySQLResultCursor* pcursor){
            std::vector<std::vector<MySQLCell>> matrix;
            pcursor->fetch_all(matrix);
            string msg = matrix[0][2].as_string();
            resp->String(msg);
        });
    });

    //在wfrest中显式使用序列
    httpserver.GET("/wfrest/series", [](const HttpReq*, HttpResp*resp, SeriesWork * series){
        auto timerTask = WFTaskFactory::create_timer_task(1000 * 1000, 
        [resp](WFTimerTask * ){
            printf("timerCallback is running.\n");
            resp->String("timer callback");
        });
        series->push_back(timerTask);
    });


    httpserver.GET("/wfrest/mysql3", 
    [](const HttpReq*, HttpResp * httpResp, SeriesWork * series){
        string url("mysql://root:1234@localhost");
        auto mysqlTask = WFTaskFactory::create_mysql_task(url, 1,
        [httpResp](WFMySQLTask * mysqltask){
            //0. 对任务的状态进行检测
            int state = mysqltask->get_state();
            int error = mysqltask->get_error();
            if(state != WFT_STATE_SUCCESS) {
                printf("%s\n", WFGlobal::get_error_string(state, error));
                return;
            }
            //1. 检测SQL语句是否存在语法错误
            auto resp = mysqltask->get_resp();
            if(resp->get_packet_type() == MYSQL_PACKET_ERROR) {
                printf("ERROR %d: %s\n", resp->get_error_code(),
                       resp->get_error_msg().c_str());
                return;
            }
            printf("sql sentence is ok.\n");
            using namespace protocol;
            MySQLResultCursor cursor(resp);
            if(cursor.get_cursor_status() == MYSQL_STATUS_OK) {
                printf("Query OK. %llu row affected.\n",cursor.get_affected_rows());
            } else if(cursor.get_cursor_status() == MYSQL_STATUS_GET_RESULT) {
                //读操作
                vector<vector<MySQLCell>> matrix;
                cursor.fetch_all(matrix);
                string msg = matrix[1][1].as_string();
                httpResp->String(msg);
            }        
        });
        string sql("select * from cloudisk.tbl_user_token");
        mysqlTask->get_req()->set_query(sql);
        series->push_back(mysqlTask);
    });

    if(httpserver.track().start(8888) == 0) {
        //列出当前服务器上部署的服务
        httpserver.list_routes();
        waitGroup.wait();
        httpserver.stop();
    } else {
        printf("HttpServer start failed.\n");
    }
}


int main()
{
    test0();
    printf("exit main\n");
    return 0;
}

